﻿#include "ArkXbpManag.h"
#include "ArkRandHelper.h"

namespace kd
{
	// KCXP唯一群体标识
	static std::string mxGroupID = "KINGDOMARKMINNER";

	// 进程单例模式
	ArkXbpManag* ArkXbpManag::ins()
	{
		static ArkXbpManag instance;
		return &instance;
	}

	std::string ArkXbpManag::GetGroupID()
	{
		static std::once_flag executeOncetime;
		std::call_once(executeOncetime, []()
		{
			ArkRandom arkRand;
			pid_t pidnum = getpid();
			std::string pidstr = std::to_string(pidnum);

			// 初始化GroupID
			uint32_t len = 16 - pidstr.length();
			mxGroupID = arkRand.RandString(len) + pidstr;
		});
		return mxGroupID;
	}

	ArkXbpManag::ArkXbpManag()
	{
	}

	ArkXbpManag::~ArkXbpManag()
	{
		// 确保线程安全地操作
		ARK_LOCK_GUARD(mxLocker);

		// 遍历KCXP请求连接池
		mrKcxpPools.clear();

		// 遍历KCXP应答连接池
		msKcxpPools.clear();
	}

	void ArkXbpManag::SetWaitTimes(int times)
	{
		mxWaitTimes = times;
	}

	bool ArkXbpManag::AddKcxpPool(const ArkKcxpSvr& xpSvrinfo, const int nPoolsize)
	{
		ARK_LOCK_GUARD(mxLocker);

		std::ostringstream ossOption;
		ossOption << xpSvrinfo.kcxp_addr << ":" << xpSvrinfo.kcxp_port;
		std::string xbpMarker = ossOption.str();
		//LOG_INFO("%s  [%d]", xbpMarker.c_str(), mrKcxpPools.size());

		ArkKcxpSvr tmSvrinfo = xpSvrinfo;
		//tmSvrinfo.strReqQ = tmSvrinfo.strResQ;

		// KCXP请求连接池
		ArkXbpPool* pReqKcxpPool = mrKcxpPools.find_value(xbpMarker);
		if (pReqKcxpPool != nullptr) return true;

		// KCXP应答连接池
		ArkXbpPool* pResKcxpPool = msKcxpPools.find_value(xbpMarker);
		if (pResKcxpPool != nullptr) return true;

		pReqKcxpPool = new ArkXbpPool(xpSvrinfo, nPoolsize);
		pResKcxpPool = new ArkXbpPool(tmSvrinfo, nPoolsize);
		if (pReqKcxpPool && pResKcxpPool)
		{
			// KCXP请求连接池
			pReqKcxpPool->SetWaitTimes(mxWaitTimes);
			mrKcxpPools.insert(xbpMarker, pReqKcxpPool);

			// KCXP应答连接池
			pResKcxpPool->SetWaitTimes(mxWaitTimes);
			msKcxpPools.insert(xbpMarker, pResKcxpPool);
			return true;
		}

		return false;
	}

	ArkXbpPool* ArkXbpManag::PeekRequestPool(const ArkKcxpSvr& xpSvrinfo, bool isExclusive)
	{
		if (isExclusive) mxLocker.lock();

		std::ostringstream ossOption;
		ossOption << xpSvrinfo.kcxp_addr << ":" << xpSvrinfo.kcxp_port;
		std::string xbpMarker = ossOption.str();

		// 从管理池中获取节点
		ArkXbpPool* pKcxpPool = mrKcxpPools.find_value(xbpMarker);

		if (isExclusive) mxLocker.unlock();

		return pKcxpPool;
	}

	ArkXbpPool* ArkXbpManag::PeekResponsPool(const ArkKcxpSvr& xpSvrinfo, bool isExclusive)
	{
		if (isExclusive) mxLocker.lock();

		std::ostringstream ossOption;
		ossOption << xpSvrinfo.kcxp_addr << ":" << xpSvrinfo.kcxp_port;
		std::string xbpMarker = ossOption.str();

		// 从管理池中获取节点
		ArkXbpPool* pKcxpPool = msKcxpPools.find_value(xbpMarker);

		if (isExclusive) mxLocker.unlock();

		return pKcxpPool;
	}
}